<template>
  <div>
    <upload-oss-base
      v-bind="$attrs"
      v-on="$listeners"
      class="upload-oss"
      :accept="selfAccept"
      :file-list="fileList"
      :list-type="selfListType"
      :show-file-list="selfShowFileList"
      :on-preview="selfOnPreview"
      :on-change="selfOnChange"
      :on-remove="selfOnRemove"
    >
      <template v-slot:default="file">
        <div v-if="isSingleImagePreviewType" class="single-wrap">
          <img class="single-image" :src="singleImageObj.url" alt="" />
          <div class="single-mask"></div>
          <div class="single-actions">
            <span v-if="singleImageObj.url" class="mr-3" @click.stop="handleSingleImageObjPreview">
              <i class="action-icon el-icon-zoom-in"></i>
            </span>
            <span>
              <i class="action-icon el-icon-plus"></i>
            </span>
          </div>
        </div>
        <slot :file="file"></slot>
      </template>

      <template v-slot:file="{ file }">
        <slot name="file" :file="file"></slot>
      </template>

      <template v-slot:trigger>
        <slot v-if="$slots.trigger" name="trigger"></slot>
        <i v-else-if="selfListType === 'picture-card'" class="el-icon-plus"></i>
        <el-button v-else type="primary">{{ triggerText }}</el-button>
      </template>

      <slot name="tip"></slot>
    </upload-oss-base>
  </div>
</template>
<script>
function noop() {}

export default {
  name: 'UploadOss',
  components: {},
  props: {
    triggerText: { type: String, default: '点击上传' },
    fileList: Array,
    showFileList: { type: Boolean, default: true },
    listType: { type: String, default: 'text' },
    singleImage: Boolean,
    accept: String,

    onPreview: { type: Function, default: noop },
    onChange: { type: Function, default: noop },
    onRemove: { type: Function, default: noop },
  },
  data() {
    return {
      singleImageObj: {},
    }
  },
  computed: {
    selfShowFileList() {
      return this.singleImage ? false : this.showFileList
    },
    selfListType() {
      return this.singleImage ? 'picture-card' : this.listType
    },
    selfAccept() {
      return this.singleImage ? 'image/*' : this.accept
    },
    isImageType() {
      return ['picture-card', 'picture'].includes(this.selfListType)
    },
    isSingleImagePreviewType() {
      return !this.selfShowFileList && !this.$slots.default
    },
  },
  watch: {
    fileList: {
      handler: function (val) {
        this.getSingleImageObj(val)
      },
      deep: true,
      immediate: true,
    },
  },
  created() {},
  mounted() {},
  methods: {
    submit() {
      return this.$children[0].submit()
    },
    selfOnPreview(file, fileList) {
      if (this.isImageType) {
        this.$utils.viewer({
          images: fileList,
          index: fileList.findIndex(item => item.uid === file.uid) || 0,
        })
      }

      this.onPreview(file, fileList)
    },
    handleSingleImageObjPreview() {
      this.$utils.viewer({
        images: [this.singleImageObj],
        index: 0,
      })
    },
    selfOnChange(file, fileList) {
      this.getSingleImageObj(fileList)
      this.onChange(file, fileList)
    },
    selfOnRemove(file, fileList) {
      this.singleImageObj = {}
      this.onRemove(file, fileList)
    },
    getSingleImageObj(fileList = []) {
      const len = fileList.length
      this.singleImageObj = len ? fileList[len - 1] : {}
    },
  },
}
</script>
<style lang="scss" scoped>
/deep/ .el-upload {
  position: relative;
}
.single-wrap {
  position: absolute;
  top: 0;
  left: 0;
  width: 146px;
  height: 146px;
  &:hover,
  &:focus {
    .single-mask {
      opacity: 0.8;
    }
    .single-actions {
      opacity: 0.8;
    }
  }
}
.single-image {
  max-width: 100%;
  max-height: 146px;
}
.single-mask {
  position: absolute;
  top: 2px;
  bottom: 0;
  left: 2px;
  right: 0;
  border-radius: 4px;
  background-color: rgba(0, 0, 0, 0.2);
  background-color: var(--primary-light-9);
  opacity: 0;
  transition: opacity 0.3s;
}
.single-actions {
  position: absolute;
  text-align: center;
  top: 0px;
  left: 0px;
  width: 100%;
  opacity: 0;
  transition: opacity 0.3s;
  .action-icon {
    color: #999;
    font-size: 28px;
  }
}
</style>
